﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace lumo.display.animation2D
{
    /// <summary>
    /// Serial animation for 2D objects.
    /// </summary>
    public class SerialAnimation2D : IInternalAnimation2D, IAnimation2D
    {
        // THe parent object
        private object CurrentObject = null;
        private List<IInternalAnimation2D> AnimationList = new List<IInternalAnimation2D>();
        private List<IInternalAnimation2D> OriginalAnimationList = new List<IInternalAnimation2D>();
        private bool Loop = false;

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="CurrentObject">The animated object</param>
        /// <param name="Loop">Looping?</param>
        public SerialAnimation2D(object CurrentObject = null, bool Loop = false)
        {
            // Set the object.
            this.CurrentObject = CurrentObject;
            this.Setupped = false;
            this.Loop = Loop;
        }

        /// <summary>
        /// Add an animation
        /// </summary>
        /// <param name="Animation">The animation to add.</param>
        public void Add(object Animation)
        {
            // Set the parent object.
            if (!(Animation is IInternalAnimation2D))
                throw new Exception("Animation is not valid");
            // Add the animation.
            else
                OriginalAnimationList.Add(Animation as IInternalAnimation2D);
        }

        /// <summary>
        /// Setup the animations.
        /// </summary>
        /// <param name="ParentObject">The parent object of the animations.</param>
        public void Setup(object ParentObject)
        {
            // Alredy setupped.
            if (this.Setupped)
                return;

            // Set the parent object.
            if (CurrentObject == null)
                CurrentObject = ParentObject;

            // Clear old animation list. Ensure it is empty.
            AnimationList.Clear();
            // Add the animations
            foreach (var Anim in OriginalAnimationList)
                AnimationList.Add(Anim);

            // The object is setupped.
            this.Setupped = true;
        }


        /// <summary>
        /// Reset the animations.
        /// </summary>
        public void Reset()
        {
            foreach (IInternalAnimation2D anim in OriginalAnimationList)
                anim.Reset();
            // Clear current animations.
            AnimationList.Clear();
            this.Setupped = false;
        }

        /// <summary>
        /// Check if it is setupped.
        /// </summary>
        public bool Setupped { get; private set; }

        /// <summary>
        /// Check if animation has finished.
        /// </summary>
        /// <returns>True if it has</returns>
        public bool Finished { get { if (Loop) return false;  return (AnimationList.Count <= 0); } }

        /// <summary>
        /// Update the animations.
        /// </summary>
        /// <param name="Game"></param>
        public void Update(LumoComponent Game)
        {
            // Reset the animations if on loop and finished.
            if ((AnimationList.Count <= 0) && Loop)
                Reset();

            if (!this.Setupped)
                this.Setup(CurrentObject);

            // Check for animation list
            while (AnimationList.Count > 0)
            {
                if (!AnimationList[0].Setupped)
                    AnimationList[0].Setup(CurrentObject);
                if (AnimationList[0].Finished)
                {
                    AnimationList.RemoveAt(0);
                    continue;
                }
                AnimationList[0].Update(Game);
                break;
            }
        }
    }
}
